unit uInNomineSystem;

interface

uses
  Contnrs;

const
  NUMBER_OF_CHARACTER_CONCEPTS = 9;
  NUMBER_OF_ANGEL_CHOIRS = 8;
  NUMBER_OF_DEMON_BANDS = 7;
  NUMBER_OF_ARCHANGELS = 13;
  NUMBER_OF_DEMON_PRINCES = 14;
  NUMBER_OF_CHARACTERISTICS = 6;
  NUMBER_OF_SONGS = 14;
  NUMBER_OF_SKILLS = 32;
  NUMBER_OF_SERVANT_CLASSES = 6;

type
  (* basic types *)
  TAttributeValue = integer;
  TEssence = integer;
  TDissonance = integer;
  TLevelOfDisturbance = integer;
  TDistinctionLevel = integer;
  TCharacterConceptsForcePointsArray = array [0..7] of integer;

  (* enumerates *)
  TCharacterConcept = (angel,
                       demon,
                       outcast,
                       renegade,
                       remnant,
                       soldierGod,
                       soldierHell,
                       undead,
                       mundane);

  PCharacterConcept = ^TCharacterConcept;
  
  TRealm = (corporeal, ethereal, celestial);
  TForcesType = TRealm;
  TCharacteristicType = (strength, intelligence, will, agility, precision, perception);
  TServantClass = (class1 = 1,
                   class2,
                   class3,
                   class4,
                   class5,
                   class6);

                     // angelic
  TCelestialKind =  (seraphim,
                     cherubim,
                     ofanim,
                     elohim,
                     malakim,
                     kyriotates,
                     mercurians,
                     grigori,
                     // demonic
                     balseraphs,
                     djinn,
                     calabim,
                     habbalah,
                     lilim,
                     shedim,
                     impudites);
                     
  PCelestialKind = ^TCelestialKind;

  (* forces *)
  TForces = class
  protected
    FRealm: TRealm;
  public
    number: integer;
    attribute: array [0..1] of TAttributeValue;

    constructor Create(realm: TRealm);
  end;

  TCorporealForces = class(TForces)
  public
    constructor Create;

    property realm: TRealm read FRealm;
    property strength: TAttributeValue read attribute[0] write attribute[0];
    property agility: TAttributeValue read attribute[1] write attribute[1];
  end;

  TEtherealForces = class(TForces)
  public
    constructor Create;

    property realm: TRealm read FRealm;
    property intelligence: TAttributeValue read attribute[0] write attribute[0];
    property precision: TAttributeValue read attribute[1] write attribute[1];
  end;

  TCelestialForces = class (TForces)
  public
    constructor Create;

    property realm: TRealm read FRealm;
    property will: TAttributeValue read attribute[0] write attribute[0];
    property perception: TAttributeValue read attribute[1] write attribute[1];
  end;

  (* resource *)
  TResource = class
  public
    description: string;
    cost: integer;
    level: integer;
  end;

  TSkill = class(TResource)
  public
    attributes: set of TCharacteristicType;
    defaultPenalty: integer;
    needsSpecification: boolean;
    specification: String;

    class function Clone(skill: TSkill): TSkill;
  end;

  TSkills = array [0..NUMBER_OF_SKILLS - 1] of TSkill;

  TSong = class(TResource)
  public
    realm: TRealm;
    essenceCost: TEssence;
    levelOfDisturbance: TLevelOfDisturbance;

    class function Clone(song: TSong): TSong;
  end;

  TSongs = array [0..(NUMBER_OF_SONGS * 3) - 1] of TSong;

  TServant = class(TResource)
  public
    servantClass: TServantClass;
  end;

  TCharisma = TResource;

  TRole = class(TResource)
  public
    status: integer;
  end;

  TVessel = class(TResource)
  public
    charisma: TCharisma;
    role: TRole;
    bodyHits: integer;
  end;

  TDiscord = class(TResource)
  public
    realm: TRealm;
  end;

  (* superior *)

  TDistinction = class
  public
    description: string;
    level: TDistinctionLevel;
  end;

  TDistinctions = array [0..2] of TDistinction;

  TSuperior = class
  protected
    FWord: string;
  public
    name: string;
    celestialKind: PCelestialKind;
    choirAttunements: TObjectList;
    servitorAttunements: TObjectList;
    distinctions: TDistinctions;

    constructor Create(word: string);

    property word: string read FWord;
  end;

                     // archangels
  TFamousSuperior = (blandine,
                     david,
                     dominic,
                     eli,
                     gabriel,
                     janus,
                     jean,
                     jordi,
                     laurence,
                     marc,
                     michael,
                     novalis,
                     yves,
                     // demon princes
                     andrealphus,
                     asmodeus,
                     baal,
                     beleth,
                     belial,
                     haagenti,
                     kobal,
                     kronos,
                     malphas,
                     nybbas,
                     saminga,
                     valefor,
                     vapula,
                     lilith);

  TAttunement = class(TResource)
  public
    superior: TSuperior;
    //minimumEssenceCost: TEssence;

    class function Clone(attunement: TAttunement): TAttunement;
  end;

  TCharacterConceptsDescriptors = array [0..NUMBER_OF_CHARACTER_CONCEPTS - 1] of String;
  TCelestialKindsDescriptors = array [0..NUMBER_OF_ANGEL_CHOIRS + NUMBER_OF_DEMON_BANDS - 1] of String;
  TCharacteristicsDescriptors = array [0..NUMBER_OF_CHARACTERISTICS - 1] of String;
  TServantClassesDescriptors = array [0..5] of String;
  TRealmDescriptors = array [0..2] of String;
  TFamousSuperiorsNames = array [0..NUMBER_OF_ARCHANGELS + NUMBER_OF_DEMON_PRINCES - 1] of String;
  TSongsNames = array [0..NUMBER_OF_SONGS - 1] of String;
  TSkillsNames = array [0..NUMBER_OF_SKILLS - 1] of String;

const
  CHARACTER_CONCEPTS_DESCRIPTORS: TCharacterConceptsDescriptors = ('Angel',
                                                         'Demon',
                                                         'Outcast',
                                                         'Renegade',
                                                         'Remnant',
                                                         'Soldier of God',
                                                         'Soldier of Hell',
                                                         'Undead',
                                                         'Mundane');

  CELESTIAL_KINDS_DESCRIPTORS: TCelestialKindsDescriptors = ('Seraphim',
                                                       'Cherubim',
                                                       'Ofanim',
                                                       'Elohim',
                                                       'Malakim',
                                                       'Kyriotates',
                                                       'Mercurians',
                                                       'Grigori',
                                                       'Balseraphs',
                                                       'Djinn',
                                                       'Calabim',
                                                       'Habbalah',
                                                       'Lilim',
                                                       'Shedim',
                                                       'Impudites');

  FAMOUS_SUPERIORS_NAMES: TFamousSuperiorsNames = ('Blandine',
                                                  'David',
                                                  'Dominic',
                                                  'Eli',
                                                  'Gabriel',
                                                  'Janus',
                                                  'Jean',
                                                  'Jordi',
                                                  'Laurence',
                                                  'Marc',
                                                  'Michael',
                                                  'Novalis',
                                                  'Yves',
                                                  'Andrealphus',
                                                  'Asmodeus',
                                                  'Baal',
                                                  'Beleth',
                                                  'Belial',
                                                  'Haagenti',
                                                  'Kobal',
                                                  'Kronos',
                                                  'Malphas',
                                                  'Nybbas',
                                                  'Saminga',
                                                  'Valefor',
                                                  'Vapula',
                                                  'Lilith');

  CHARACTER_CONCEPTS_FORCE_POINTS: TCharacterConceptsForcePointsArray = (9, 9, 9, 9, 5, 6, 6, 5);

  CHARACTERISTICS_DESCRIPTORS: TCharacteristicsDescriptors = ('Strength',
                                                              'Intelligence',
                                                              'Will',
                                                              'Agility',
                                                              'Precision',
                                                              'Perception');

  SERVANT_CLASSES_DESCRIPTORS: TServantClassesDescriptors = ('Zombi, Ordinary Animal - 4 Forces',
                                                             'Reliever, Imp, Gremlin - 4 Forces',
                                                             'Above but as familiar, Human - 4 Forces',
                                                             'Human, Vampire - 5 forces',
                                                             'Soldier, Undead - 6 forces, Human w/ extra points - 5 Forces',
                                                             'Experienced Soldier or Undead - 7 Forces');

  REALM_DESCRIPTORS: TRealmDescriptors = ('Corporeal',
                                          'Ethereal',
                                          'Celestial');

  SONGS_NAMES: TSongsNames = ('Attraction', 'Charm', 'Dreams', 'Entropy',
                            'Form', 'Harmony', 'Healing', 'Light',
                            'Motion', 'Possession', 'Projection', 'Shield',
                            'Thunder', 'Tongues');

  SKILLS_NAMES: TSkillsNames = ('Acrobatics', 'Artistry', 'Chemistry', 'Climbing', 'Computer Operation',
                                'Detect Lies', 'Dodge', 'Driving', 'Eletronics', 'Emote',
                                'Engineering', 'Escape', 'Fast-Talk', 'Fighting', 'Knowledge',
                                'Languages', 'Large Weapon', 'Lockpicking', 'Lying', 'Medicine',
                                'Move Silently', 'Ranged Weapon', 'Running', 'Savoir-Faire', 'Seduction',
                                'Singing', 'Small Weapon', 'Survival', 'Swimming', 'Tactics',
                                'Throwing', 'Tracking');

var
  famousSuperiors: array [0..NUMBER_OF_ARCHANGELS + NUMBER_OF_DEMON_PRINCES - 1] of TSuperior;
  songs: TSongs;
  skills: TSkills;

procedure LoadFamousSuperiors;
function IsAngelic(celestialKind: TCelestialKind): boolean; overload;

implementation

uses
  uInNomineSuperiors, uInNomineSongs, uInNomineSkills;

{ TForces }

constructor TForces.Create(realm: TRealm);
begin
  FRealm := realm;

  attribute[0] := 0;
  attribute[1] := 0;
end;

{ TCorporealForces }

constructor TCorporealForces.Create;
begin
  inherited Create(corporeal);
end;

{ TEtherealForces }

constructor TEtherealForces.Create;
begin
  inherited Create(ethereal);
end;

{ TCelestialForces }

constructor TCelestialForces.Create;
begin
  inherited Create(ethereal);
end;

{ TSuperior }

constructor TSuperior.Create(word: string);
begin
  FWord := word;

  celestialKind := nil;
  
  choirAttunements := TObjectList.Create(True);
  servitorAttunements := TObjectList.Create(True);
end;

procedure LoadFamousSuperiors;
var
  i: integer;
begin
  for i := 0 to NUMBER_OF_ARCHANGELS + NUMBER_OF_DEMON_PRINCES - 1 do
    famousSuperiors[i] := GetFamousSuperior(TFamousSuperior(i));
end;

function IsAngelic(celestialKind: TCelestialKind): boolean;
begin
  Result := (Ord(celestialKind) < NUMBER_OF_ANGEL_CHOIRS);  
end;

{ TAttunement }

class function TAttunement.Clone(attunement: TAttunement): TAttunement;
begin
  Result := TAttunement.Create;
  Result.description := attunement.description;
  Result.cost := attunement.cost;
  Result.level := attunement.level;
  Result.superior := attunement.superior;
end;

{ TSong }

class function TSong.Clone(song: TSong): TSong;
begin
  Result := TSong.Create;
  Result.description := song.description;
  Result.cost := song.cost;
  Result.level := song.level;
  Result.realm := song.realm;
  Result.essenceCost := song.essenceCost;
  Result.levelOfDisturbance := song.levelOfDisturbance;
end;

{ TSkill }

class function TSkill.Clone(skill: TSkill): TSkill;
begin
  Result := TSkill.Create;
  Result.description := skill.description;
  Result.cost := skill.cost;
  Result.level := skill.level;
  Result.attributes := skill.attributes;
  Result.defaultPenalty := skill.defaultPenalty;
  Result.needsSpecification := skill.needsSpecification;
end;

initialization
  LoadFamousSuperiors;
  songs := GetAllSongs;
  skills := GetAllSkills;

end.
